package nl.boelen.game.level;

import java.util.Random;
import nl.boelen.game.Game;
import nl.boelen.game.graphics.Screen;
import nl.boelen.game.handler.MouseHandler;
import nl.boelen.game.level.tiles.Tile;

public class Level {
    private byte[] groundTiles;
    private MouseHandler mouseHandler;
    private BuildMenu buildMenu;
    private Screen screen;
    private int width;
    private int height;

    public Level(MouseHandler mouseHandler, Screen screen) {
        this.mouseHandler = mouseHandler;
        this.screen = screen;
        buildMenu = new BuildMenu(screen);

        // TODO generate from file
        loadLevel("aFile.txt");
    }

    private void loadLevel(String string) {
        // TODO load a level from a file
        this.width = 100;
        this.height = 100;
        groundTiles = new byte[width * height];

        Random r = new Random();
        byte id = 0;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (y == 0 || y == height - 1 || x == 0 || x == width - 1) {
                    id = Tile.WATER.getId();
                } else {
                    switch (r.nextInt(4)) {
                        case 0 :
                            id = Tile.GRASS0.getId();
                            break;
                        case 1 :
                            id = Tile.GRASS1.getId();
                            break;
                        case 2 :
                            id = Tile.GRASS2.getId();
                            break;
                        case 3 :
                            id = Tile.GRASS3.getId();
                            break;
                        default :
                            id = Tile.VOID.getId();
                            break;
                    }
                }
                groundTiles[x + y * width] = id;
            }
        }
    }

    public void render() {
        renderTiles();
        renderMousePos();
        buildMenu.render();
    }

    private void renderTiles() {
        int xOffset = screen.getOffsetX();
        int yOffset = screen.getOffsetY();
        int b = Screen.BORDER;
        if (xOffset < 0 - b - screen.left_area) {
            xOffset = -b - screen.left_area;
        }
        if (xOffset > ((width * Game.TILE_SIZE) - screen.width + b + screen.right_area)) {
            xOffset = ((width * Game.TILE_SIZE) - screen.width + b + screen.right_area);
        }
        if (yOffset < 0 - b - screen.top_area) {
            yOffset = -b - screen.top_area;
        }
        if (yOffset > ((height * Game.TILE_SIZE) - screen.height + b + screen.bottom_area)) {
            yOffset = ((height * Game.TILE_SIZE) - screen.height + b + screen.bottom_area);
        }

        screen.setOffset(xOffset, yOffset);

        int firstRow = screen.getOffsetY() / Game.TILE_SIZE;
        if (firstRow < 0) {
            firstRow = 0;
        }
        int firstColumn = screen.getOffsetX() / Game.TILE_SIZE;
        if (firstColumn < 0) {
            firstColumn = 0;
        }
        int lastRow = (screen.getOffsetY() + screen.height - screen.bottom_area) / Game.TILE_SIZE;
        if (lastRow > height - 1) {
            lastRow = height - 1;
        }
        int lastColumn = (screen.getOffsetX() + screen.width) / Game.TILE_SIZE;
        if (lastColumn > width - 1) {
            lastColumn = width - 1;
        }

        for (int y = firstRow; y <= lastRow; y++) {
            for (int x = firstColumn; x <= lastColumn; x++) {
                getTile(x, y).render(screen, this, x * Game.TILE_SIZE, y * Game.TILE_SIZE);
            }
        }
    }

    private void renderMousePos() {
        int mouseX = mouseHandler.getMouseX();
        int mouseY = mouseHandler.getMouseY();
        int tileX = (mouseX + screen.getOffsetX()) / Game.TILE_SIZE;
        int tileY = (mouseY + screen.getOffsetY()) / Game.TILE_SIZE;
        Tile.MOUSEOVER.render(screen, this, tileX * Game.TILE_SIZE, tileY * Game.TILE_SIZE);
    }

    public void tick() {

    }

    private Tile getTile(int x, int y) {
        if (x < 0 || x > width || y < 0 || y > height) {
            return Tile.VOID;
        }
        return Tile.tiles[groundTiles[x + y * width]];
    }
}